package com.scs.application.modules.base.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.scs.application.core.exception.ValidException;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.enums.MatrBusinessType;
import com.scs.application.modules.base.annotation.MatrCanPass;
import com.scs.application.modules.base.entity.Matr;
import com.scs.application.modules.base.service.MatrService;
import com.scs.application.modules.sys.model.RestResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Aspect
@Component
public class MatrCanPassAspect {
    public static final Logger logger = LoggerFactory.getLogger(MatrCanPassAspect.class);

    @Autowired
    private MatrService matrService;

    @Pointcut("@annotation(com.scs.application.modules.base.annotation.MatrCanPass)")
    public void canPassPointcut() {

    }

    @Before("canPassPointcut()")
    public void beforePointcut(JoinPoint joinPoint){
        // 此处进入到方法前  自己可以实现一些业务逻辑
    }

    @Around("canPassPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info("+++++++++++++++++++++++doAround+++++++++++++++++++++++++");
        //目标方法实体
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        boolean hasMethodLogAnno = method.isAnnotationPresent(MatrCanPass.class);
        //没加注解 直接执行返回结果
        if (!hasMethodLogAnno) {
            return joinPoint.proceed();
        }
        MatrCanPass annotation = method.getAnnotation(MatrCanPass.class);  //获取方法上的注解
        String  businessType = annotation.businessType();  //获取注解函数值
        /*// 获取request
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        Map<String, String[]> pram = request.getParameterMap();*/

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] params = methodSignature.getParameterNames();// 获取参数名称
        Object[] args = joinPoint.getArgs();// 获取参数值
        if (null == params || params.length == 0){
            String mes = "Using MatrCanPass annotation, the parameter is not passed, and the parameter is not valid.";
            logger.info(mes);
            throw new Exception(mes);
        }
        List<String> idList = new ArrayList<String>();
        if (StringUtils.isBlank(businessType)){//那就是从方法内部且通过MatrPassUtil调用进入的
            businessType = (String) args[0];
            idList = (ArrayList) args[1];
        } else {//通过controller层调进来的
            String json =  JSON.toJSONString(args);//有两层JSON数组
            if(businessType.contains("_item")){//单条保存
                businessType = businessType.replaceAll("_item","");
                JSONArray cases0 = JSONArray.parseArray(json);//第一层
                JSONObject cases = cases0.getJSONObject(0);//第二层
                idList.add(cases.getString("matrId"));
            } else {//批量保存
                JSONArray cases0 = JSONArray.parseArray(json);//第一层
                JSONArray cases = cases0.getJSONArray(0);//第二层
                for(int i = 0; i < cases.size(); i++){
                    idList.add(cases.getJSONObject(i).getString("matrId"));
                }
            }

        }

        MatrBusinessType type = MatrBusinessType.valueOf(businessType);
        this.checkMatrPass(idList, type.value());
        return joinPoint.proceed();
    }

    /**
     * 在切入点return内容之后切入内容（可以用来对处理返回值做一些加工处理）
     * @param joinPoint
     */
    @AfterReturning("canPassPointcut()")
    public void doAfterReturning(JoinPoint joinPoint) {
    }

    private void checkMatrPass(List<String> idList, int businessType) {
        // 这实现自己的业务
        try {
            //自己的业务逻辑
            if (CollectionUtils.isEmpty(idList)) {
                return;
            }
            RestResult restResult = matrService.matrCanPass(idList,businessType + "");
            if (restResult.isSuccess()) {
                List<Matr> forbiddenList = (List<Matr>) restResult.getData();
                throw new ValidException("以下商品已被禁用，如需使用，请联系运营解禁<br/>%s",
                        StringUtils.join(forbiddenList.stream().map(item -> StringUtils.replaceSpecStr(item.getName()))
                                .distinct().collect(Collectors.toList()),",")
                );
            }
        } catch (Exception e) {
            logger.error("checkMatrPass.err",e);
            throw new ValidException(e.getMessage());
        }
    }
}
